package com.congwulin.wechat.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 类属性
 */
public class ClassField {
    /**
     * 属性
     */
    private Field field;

    /**
     * get方法
     */
    private Method getter;

    /**
     * set方法
     */
    private Method setter;

    /**
     * 属性的类型
     */
    private Class<?> type;

    /**
     * 类的属性构造函数
     *
     * @param field 属性
     * @param getter get方法
     * @param setter set方法
     */
    public ClassField(Field field, Method getter, Method setter) {
        this.field = field;
        this.type = field.getType();
        this.getter = getter;
        this.setter = setter;
    }

    /**
     * 获取属性名
     *
     * @return 属性名
     */
    public String getName() {
        return this.field.getName();
    }

    /**
     * 获取属性的类型
     *
     * @return 属性的类型
     */
    public Class<?> getType() {
        return this.type;
    }

    /**
     * 获取对象实例的当前属性的值
     *
     * @param instance 对象实例
     * @return 当前属性的值
     */
    public Object getValue(Object instance) {
        Object value = null;
        try {
            value = this.getter.invoke(instance, new Object[0]);
        }
        catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }
        catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        }
        catch (InvocationTargetException ex) {
            throw new RuntimeException(ex);
        }
        return value;
    }

    /**
     * 给对象实例的当前属性设置值
     *
     * @param instance 对象实例
     * @param value 值
     */
    public void setValue(Object instance, Object value) {
        Object[] args = new Object[] {
                value
        };
        try {
            this.setter.invoke(instance, args);
        }
        catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }
        catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        }
        catch (InvocationTargetException ex) {
            throw new RuntimeException(ex);
        }
    }
}
